﻿

#include "zyComboBox.h"


DarkMoonUI::zyComboBox::zyComboBox()
{
	SetMember(L"this", (LONG_PTR)this);
	m_obj->setWndProc(zyComboBox_WndProc);
	m_obj->setChildWndProc(zyComboBox_ChildWndProc);
	m_obj->setDestroy(zyComboBox_Destroy);
}
DarkMoonUI::zyComboBox::~zyComboBox()
{

}
void DarkMoonUI::zyComboBox::OnNCDestroy()
{
	zyEditBox* pEdit = (zyEditBox*)GetMember(L"pEdit");
	if (pEdit != nullptr) {
		pEdit->getObject()->release();
		delete pEdit;
		SetMember(L"pEdit", 0);
	}
	zyListBox* pList = (zyListBox*)GetMember(L"pList");
	if (pList != nullptr) {
		pList->getObject()->release();
		delete pList;
		SetMember(L"pList", 0);
	}
}
void WINAPI DarkMoonUI::zyComboBox::zyComboBox_Destroy(zyObject* obj)
{
	zyComboBox* zyb = (zyComboBox*)obj->getPtrData(L"this");
	zyb->OnNCDestroy();
	zyCommandCtrol::zyCommand_Destroy(obj);
}
LRESULT WINAPI DarkMoonUI::zyComboBox::zyComboBox_ChildWndProc(zyObject* obj, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL* bHandle)
{
	if (message == WM_COMMAND)
	{
		short id = LOWORD(wParam);// & 65535); //LOWORD
		int code = HIWORD(wParam);
		if (code == CBN_SELCHANGE) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnSelChange");
			if (evtPtr != nullptr) {
				evtPtr->handler<LRESULT>(lParam ,id);
			}
		}
		else if (code == CBN_EDITCHANGE) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnEditChange");
			if (evtPtr != nullptr)
				evtPtr->handler<LRESULT>(lParam, id);
		}
		else if (code == CBN_DROPDOWN) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnDropDown");
			if (evtPtr != nullptr)
				evtPtr->handler<LRESULT>(lParam, id);
		}
		else if (code == CBN_CLOSEUP) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnCloseUp");
			if (evtPtr != nullptr)
				evtPtr->handler<LRESULT>(lParam, id);
		}
		else if (code == CBN_DBLCLK) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnDBClick");
			if (evtPtr != nullptr)
				evtPtr->handler<LRESULT>(lParam, id);
		}
	}
	return zyCommandCtrol::zyCommand_ChildWndProc(obj, hWnd, message, wParam, lParam, bHandle);
}
LRESULT WINAPI DarkMoonUI::zyComboBox::zyComboBox_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandled)
{
	if (uMsg == WM_NCDESTROY) {
		zyComboBox* zyb = (zyComboBox*)obj->getPtrData(L"this");
		zyb->OnNCDestroy();
	}
	return zyCommandCtrol::zyCommand_WndProc(obj, hWnd, uMsg, wParam, lParam, bHandled);
}

BOOL DarkMoonUI::zyComboBox::创建(HWND 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	if (参数_窗口风格 == 0)
		参数_窗口风格 = CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP;
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();

	return _CreateCtrol(参数_父窗口, 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格 | WS_VSCROLL /* | CBS_NOINTEGRALHEIGHT*/, 参数_扩展风格, L"ComboBox");
}

BOOL DarkMoonUI::zyComboBox::创建(zyWindow& 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	if (参数_窗口风格 == 0)
		参数_窗口风格 = CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_TABSTOP;
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();

	return _CreateCtrol(参数_父窗口.getHwnd(), 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格 | WS_VSCROLL /*| CBS_NOINTEGRALHEIGHT*/, 参数_扩展风格, L"ComboBox");
}
int DarkMoonUI::zyComboBox::加入项目(const std::wstring& 参数_项目文本, int 参数_项目数值) {
	int i = (int)sendMsg(CB_ADDSTRING, 0, (LPARAM)参数_项目文本.c_str());
	if (i != CB_ERR)
		sendMsg(CB_SETITEMDATA, i, 参数_项目数值);
	return i;
}
int DarkMoonUI::zyComboBox::插入项目(const std::wstring& 参数_项目文本, int 参数_项目索引, int 参数_项目数值) {
	int i = (int)sendMsg(CB_INSERTSTRING, 参数_项目索引, (LPARAM)参数_项目文本.c_str());
	if (i != CB_ERR)
		sendMsg(CB_SETITEMDATA, i, 参数_项目数值);
	return i;
}
bool DarkMoonUI::zyComboBox::置现行选中项(int 参数_项目索引) {
	int i = (int)sendMsg(CB_SETCURSEL, 参数_项目索引, 0);
	if (i != CB_ERR)
		return true;
	return false;
}
int DarkMoonUI::zyComboBox::取现行选中项() {
	return (int)sendMsg(CB_GETCURSEL, 0, 0);
}
bool DarkMoonUI::zyComboBox::置最大文本长度(int 参数_最大长度) {//设置组合框中的编辑框最大文本长度。
	return sendMsg(CB_LIMITTEXT, 参数_最大长度, 0) != 0;
}
std::wstring DarkMoonUI::zyComboBox::取项目文本(int 参数_项目索引) {//Unicode文本。返回组合框指定索引项目文本
	std::wstring 局部_文本;
	局部_文本.reserve((int)sendMsg(CB_GETLBTEXTLEN, 参数_项目索引, 0) * 2 + 2);
	sendMsg(CB_GETLBTEXT, 参数_项目索引, (LPARAM)局部_文本.c_str());
	return 局部_文本;
}
bool DarkMoonUI::zyComboBox::置项目文本(int 参数_项目索引, const std::wstring& 参数_项目文本) {
	int count = (int)sendMsg(CB_GETCOUNT, 0, 0);
	if (参数_项目索引 < 0 || 参数_项目索引 >= count)
		return false;
	int current = (int)sendMsg(CB_GETCURSEL, 0, 0);
	int lParam = (int)sendMsg(CB_GETITEMDATA, 参数_项目索引, 0);
	sendMsg(CB_DELETESTRING, 参数_项目索引, 0);
	int 局部_索引 = (int)sendMsg(CB_INSERTSTRING, 参数_项目索引, (LPARAM)参数_项目文本.c_str());
	sendMsg(CB_SETITEMDATA, 局部_索引, lParam);
	if (current == 局部_索引)
		sendMsg(CB_SETCURSEL, 局部_索引, 0);
	return true;
}
bool DarkMoonUI::zyComboBox::选中指定项(const std::wstring& 参数_项目文本, int 参数_起始位置) {//设置指定文本相匹配的项目来选择项目。成功返回真，失败返回假。
	return sendMsg(CB_SELECTSTRING, 参数_起始位置, (LPARAM)参数_项目文本.c_str()) != 0;
}
int DarkMoonUI::zyComboBox::取项目数() {//返回项目总数。返回-1表示失败。
	return (int)sendMsg(CB_GETCOUNT, 0, 0);
}
DarkMoonUI::zyEditBox* DarkMoonUI::zyComboBox::取编辑框() {//当组合框风格为"组合框_允许编辑"时，获取其中的编辑框控件
	COMBOBOXINFO info = { 0 };
	zyEditBox* pEdit = (zyEditBox*)GetMember(L"pEdit");
	if (pEdit != nullptr) {
		return pEdit;
	}
	info.cbSize = sizeof(COMBOBOXINFO);
	SendMessage(取窗口句柄(), CB_GETCOMBOBOXINFO, 0, (LPARAM)&info);
	if (IsWindow(info.hwndItem) == 0)
		return pEdit;
	pEdit = new zyEditBox();
	pEdit->_BindWindow(info.hwndItem);
	zyObject* obj = pEdit->getObject();
	if(obj)
		obj->addRef();
	//IUnknown_AddRef (pEdit)
	SetMember(L"pEdit", (LONG_PTR)pEdit);
	return pEdit;
}
DarkMoonUI::zyListBox* DarkMoonUI::zyComboBox::取列表框()
{
    COMBOBOXINFO info = { sizeof(COMBOBOXINFO) };
    zyListBox* pList = reinterpret_cast<zyListBox*>(GetMember(L"pList"));

    if (pList != nullptr) {
        return pList;
    }

    HWND hwndCombo = 取窗口句柄();
    if (!SendMessage(hwndCombo, CB_GETCOMBOBOXINFO, 0, reinterpret_cast<LPARAM>(&info)) || !IsWindow(info.hwndList)) {
        throw std::runtime_error("Failed to get combobox info or list window handle is invalid.");
    }

    pList = new zyListBox();
    if (!pList->_BindWindow(info.hwndList)) {
        delete pList;
        throw std::runtime_error("Failed to bind list window.");
    }

    zyObject* obj = pList->getObject();
    if (obj) {
        obj->addRef();
    }

    SetMember(L"pList", reinterpret_cast<LONG_PTR>(pList));

    return pList;
}
int DarkMoonUI::zyComboBox::取项目数值(int 参数_项目索引) {//返回指定项目的数值。
	return (int)sendMsg(CB_GETITEMDATA, 参数_项目索引, 0);
}
bool DarkMoonUI::zyComboBox::置项目数值(int 参数_项目索引, int 参数_数值) {//设置指定项目数值。
	return sendMsg(CB_SETITEMDATA, 参数_项目索引, 参数_数值) != 0;
}
int DarkMoonUI::zyComboBox::删除项目(int 参数_项目索引) {//删除组合框指定项目,返回剩余的项目总数。
	return (int)sendMsg(CB_DELETESTRING, 参数_项目索引, 0);
}
bool DarkMoonUI::zyComboBox::清空() {//删除组合框所有项目
	return sendMsg(CB_RESETCONTENT, 0, 0) != 0;
}
bool DarkMoonUI::zyComboBox::显示列表(bool 参数_是否显示) {//设置组合框中的列表框是否显示。
	int 局部_临时 = 参数_是否显示 ? 1 : 0;
	return sendMsg(CB_SHOWDROPDOWN, 局部_临时, 0) != 0;
}
int DarkMoonUI::zyComboBox::查找(const std::wstring& 参数_欲查找文本, int 参数_起始位置) {//返回-1表示没有找到。否则将返回找到的项目索引，索引从0开始。
	return (int)sendMsg(CB_FINDSTRING, 参数_起始位置, (LPARAM)参数_欲查找文本.c_str());
}
int DarkMoonUI::zyComboBox::精确查找(const std::wstring& 参数_欲查找文本, int 参数_起始位置) {//本命令与查找相比，必须文本完全匹配才能找到项目。成功返回项目索引，失败返回-1。
	return (int)sendMsg(CB_FINDSTRINGEXACT, 参数_起始位置, (LPARAM)参数_欲查找文本.c_str());
}
RECT DarkMoonUI::zyComboBox::取列表矩形() {//取组合框中列表框的屏幕位置。
	RECT 局部_位置 = { 0 };
	sendMsg(CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&局部_位置);
	return 局部_位置;
}
bool DarkMoonUI::zyComboBox::置被选择文本(int 参数_起始位置, int 参数_结束位置) {//设置组合框中编辑框的文本为被选择状态。
	int 局部_位置 = MAKELPARAM(参数_起始位置, 参数_结束位置);
	return sendMsg(CB_SETEDITSEL, 0, 局部_位置) != 0;
}
void DarkMoonUI::zyComboBox::取被选择文本(int& 参数_起始位置, int& 参数_结束位置) {//取组合框中编辑框被选择文本的起始位置和结束位置。
	int 局部_位置 = (int)sendMsg(CB_GETEDITSEL, 0, 0);
	参数_起始位置 = LOWORD(局部_位置);
	参数_结束位置 = HIWORD(局部_位置);
}
bool DarkMoonUI::zyComboBox::禁止F4显示列表(bool 参数_是否禁止) {//参数留空为取，否则为置
	int 局部_标志 = 参数_是否禁止 ? 1 : 0;
	sendMsg(CB_SETEXTENDEDUI, 局部_标志, 0);
	return sendMsg(CB_GETEXTENDEDUI, 0, 0) != 0;
}